package com.leigq.www.producer.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.leigq.www.common.entity.Order;
import com.leigq.www.producer.entity.BrokerMessageLog;
import com.leigq.www.producer.mapper.BrokerMessageLogMapper;
import com.leigq.www.producer.mapper.OrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.UUID;

/**
 * 订单服务
 * <p>
 * 创建人：asus <br>
 * 创建时间：2019-02-16 21:24 <br>
 * <p>
 * 修改人： <br>
 * 修改时间： <br>
 * 修改备注： <br>
 * </p>
 */
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class OrderService {

    /**
     * The Order mapper.
     */
    @Resource
    private OrderMapper orderMapper;

    /**
     * The Message log mapper.
     */
    @Resource
    private BrokerMessageLogMapper messageLogMapper;

    /**
     * The Order sender.
     */
    @Resource
    private OrderSender orderSender;

    /**
     * The Object mapper.
     */
    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 添加订单
     * <br>创建人： asus
     * <br>创建时间： 2019-02-18 17:57
     * <br>
     *
     * @param order the order
     * @throws JsonProcessingException the json processing exception
     */
    public void insert(Order order) throws JsonProcessingException {
        // 消息发送唯一标识（可以使用雪花算法实现）
        order.setMsgId(System.currentTimeMillis() + "$" + UUID.randomUUID());
        // 业务入库
        orderMapper.insert(order);
        // 消息表记录入库，为了发送消息失败时可以取数据库的数据进行重投
        BrokerMessageLog msgLog = new BrokerMessageLog();
        msgLog.setMessage(objectMapper.writeValueAsString(orderMapper.findById(order.getId())));
        msgLog.setMsgId(order.getMsgId());
        /* 下次重试时间已在 SQL中 处理，故将此注释 */
//      Calendar calendar = Calendar.getInstance();
//      calendar.add(Calendar.MINUTE, MessageLogConstant.ORDER_TIMEOUT);
//      msgLog.setNextRetry(calendar.getTime());
        messageLogMapper.insert(msgLog);

        try {
            /* 发送消息至RabbitMQ */
            orderSender.sendOrder(order);
        } catch (Exception e) {
            // 会有定时任务做重试处理（重新投递）
            log.error("发送订单消息至RabbitMQ异常", e);
        }
    }

}
